using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using System.Diagnostics.Contracts;
using System.Windows;
using Konst3d.Efficiency.Suite;

namespace PEM
{
	internal partial class TasksViewModel
	{
		#region Commands

		public abstract class BaseCommand : ICommand
		{
			#region Constructor

			public BaseCommand(TasksViewModel model)
			{
				Contract.Requires(model != null);
				_model = model;
			}

			#endregion // Constructor

			#region ICommand Implementation

			public event System.EventHandler CanExecuteChanged;

			public abstract bool CanExecute(object parameter);
			public abstract void Execute(object parameter);

			protected void NotifyCanExecuteChanged(EventArgs args = null)
			{
				if (CanExecuteChanged != null)
				{
					CanExecuteChanged(this, args ?? EventArgs.Empty);
				}
			}

			#endregion

			#region Fields

			protected TasksViewModel _model;

			#endregion // Fields
		}

		public class AddTaskCommand : BaseCommand
		{
			#region Constructor

			public AddTaskCommand(TasksViewModel model) :
				base(model)
			{
				_model.SuiteOpened += OnSuiteChange;
				_model.SuiteClosed += OnSuiteChange;
				_model.SuiteCreated += OnSuiteChange;
				_model.SuiteDeleted += OnSuiteChange;
			}

			#endregion // Constructor

			#region ICommand Members

			public override bool CanExecute(object parameter)
			{
				return _model.Suite != null;
			}

			public override void Execute(object parameter)
			{
				_model.AddTask();
			}

			#endregion

			#region Event Handlers

			private void OnSuiteChange(ViewModelBase sender)
			{
				NotifyCanExecuteChanged();
			}

			#endregion Event Handlers
		}

		public class RemoveTaskCommand : BaseCommand
		{
			#region Constructor

			public RemoveTaskCommand(TasksViewModel model) :
				base(model)
			{
				_model.TaskSelected += OnTaskSelected;
			}

			#endregion // Constructor

			#region ICommand Members

			public override bool CanExecute(object parameter)
			{
				return _model.Selected != null;
			}

			public override void Execute(object parameter)
			{
				_model.RemoveTask();
			}

			#endregion

			#region Event Handlers

			private void OnTaskSelected(ViewModelBase sender)
			{
				NotifyCanExecuteChanged();
			}

			#endregion Event Handlers
		}

		public class EditTaskCommand : BaseCommand
		{
			#region Constructor

			public EditTaskCommand(TasksViewModel model) :
				base(model)
			{
				_model.TaskSelected += OnTaskSelected;
			}

			#endregion // Constructor

			#region ICommand Members

			public override bool CanExecute(object parameter)
			{
				return _model.Selected != null;
			}

			public override void Execute(object parameter)
			{
				_model.EditTask();
			}

			#endregion

			#region Event Handlers

			private void OnTaskSelected(ViewModelBase sender)
			{
				NotifyCanExecuteChanged();
			}

			#endregion Event Handlers
		}

		public class ChangeTaskStateCommand : BaseCommand
		{
			#region Constructor

			public ChangeTaskStateCommand(TasksViewModel model) :
				base(model)
			{
				_model.TaskSelected += OnTaskSelected;
				_model.SelectedTaskStateChanged += OnTaskSelected;
			}

			#endregion // Constructor

			#region ICommand Members

			public override bool CanExecute(object parameter)
			{
				return _model.Selected != null && _model.Selected.State != (TaskState)parameter;
			}

			public override void Execute(object parameter)
			{
				_model.ChangeTaskState((TaskState)parameter);
			}

			#endregion

			#region Event Handlers

			private void OnTaskSelected(ViewModelBase sender)
			{
				NotifyCanExecuteChanged();
			}

			#endregion Event Handlers
		}

		#endregion // Commands

		#region Commands Collection

		public class CommandsCollection
		{
			#region Properties

			public AddTaskCommand AddTask
			{
				get;
				private set;
			}

			public RemoveTaskCommand RemoveTask
			{
				get;
				private set;
			}

			public EditTaskCommand EditTask
			{
				get;
				private set;
			}

			public ChangeTaskStateCommand ChangeTaskState
			{
				get;
				private set;
			}

			#endregion // Properties

			#region Constructor

			public CommandsCollection(TasksViewModel host)
			{
				Contract.Requires(host != null);

				AddTask = new AddTaskCommand(host);
				RemoveTask = new RemoveTaskCommand(host);
				EditTask = new EditTaskCommand(host);
				ChangeTaskState = new ChangeTaskStateCommand(host);
			}

			#endregion // Constructor
		}

		#endregion // Commands Collection

		public void AddTask()
		{
			Contract.Requires(Suite != null);

			if (_createEditTaskDlg.ShowDialog(_parentWindow))
			{
				Suite.Tasks.Add(DateTime.Now,
					_createEditTaskDlg.TaskDeadLine,
					_createEditTaskDlg.TaskSeverity,
					_createEditTaskDlg.TaskTitle,
					_createEditTaskDlg.TaskDescription);

				UpdateTaskList();
			}
		}

		public void RemoveTask()
		{
			Contract.Requires(Suite != null);
			Contract.Requires(Selected != null);

			if (MessageBox.Show(_parentWindow, "Are you sure, you wish to delete this task?", "Delete task?", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
			{
				Suite.Tasks.Remove(Selected.ID);
				UpdateTaskList();
			}
		}

		public void EditTask()
		{
			Contract.Requires(Suite != null);
			Contract.Requires(Selected != null);

			if (_createEditTaskDlg.ShowDialog(_parentWindow, Selected))
			{
				Selected.Title = _createEditTaskDlg.TaskTitle;
				Selected.Description = _createEditTaskDlg.TaskDescription;
				Selected.Severity = _createEditTaskDlg.TaskSeverity;
				Selected.DeadLine = _createEditTaskDlg.TaskDeadLine;

				UpdateTaskList();
			}
		}

		public void ChangeTaskState(TaskState state)
		{
			Contract.Requires(Suite != null);
			Contract.Requires(Selected != null);

			Selected.State = state;
			Tasks.NotifyItemChanged(Selected); // TOFIX: naming ==> NotifyItemChanged

			if (SelectedTaskStateChanged != null)
			{
				SelectedTaskStateChanged(this);
			}

			if (Filter != FilterType.All)
			{
				UpdateTaskList();
			}
		}
	}
}
